//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.ssy.lingxi.pay.utils;

import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSONObject;
import com.ssy.lingxi.common.constant.Constants;
import com.ssy.lingxi.component.redis.service.IRedisStringUtils;
import com.ssy.lingxi.component.redis.serviceImpl.RedisStringUtilsImpl;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.util.ResourceUtils;

import javax.crypto.Cipher;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.URL;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

public class RSAUtil {
    private static Provider provider = new BouncyCastleProvider();
    public static RSAPublicKey publicKey = (RSAPublicKey) RSAUtil.loadPublicKey(null, null, null);
    public static RSAPublicKey tlPublicKey = (RSAPublicKey) RSAUtil.loadTLPublicKey(null);
    public static RSAPrivateKey privateKey = null;//(RSAPrivateKey) RSAUtil.loadPrivateKey(null, null, null);
    public static String rootCA = "RootCA";
    public static String certCA = "client";
    public static RSAPublicKey gwPublicKey;

    //    public static String path = "classpath:allInPay/";
    public static String path = "/usr/local/lingxi/pay/";


    private RSAUtil() {
    }

    public static void initPubKey(RSAPublicKey pubKey) {
        tlPublicKey = pubKey;
    }

    public static String encrypt(String data) throws Exception {
        return byte2hex(encrypt(tlPublicKey, data.getBytes()));
    }
    //m目前再用
    public static String encrypt(String data, String cacheParams) throws Exception {
        JSONObject resp = JSONObject.parseObject(cacheParams);
        String certPath = resp.getString("42");
        PublicKey publicKey = loadRsaTLPublicKey(certPath);
        return byte2hex(encrypt(publicKey, data.getBytes()));
    }

//    public static String decrypt(String data) throws Exception {
//        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());
//        cipher.init(2, privateKey);
//        byte[] bytes = cipher.doFinal(hex2byte(data));
//        return new String(bytes);
//    }

    /**
     * @deprecated
     */
    public static byte[] encrypt(byte[] data) throws Exception {
        return encrypt(tlPublicKey, data);
    }
/*
    public static byte[] decrypt(byte[] data) throws Exception {
        return decrypt(privateKey, data);
    }

    public static String sign(String text) throws Exception {
        return sign(privateKey, text);
    }
*/

    /**
     * 目前使用
     */
    public static String sign(String text, String cacheParams) throws Exception {
        JSONObject resp = JSONObject.parseObject(cacheParams);
        String alias = resp.getString("40");
        String path = resp.getString("41");
        String password = resp.getString("47");
        PrivateKey privateKey = loadRsaPrivateKey(alias, path, password);
        return sign(privateKey, text);
    }

    public static boolean verify(String text, String sign) throws Exception {
        return verify(tlPublicKey, text, sign);
    }

    public static String sign(PrivateKey privateKey, String text) throws Exception {
        Signature signature = Signature.getInstance("SHA1WithRSA", provider);
        text = md5(text);
        signature.initSign(privateKey);
        signature.update(text.getBytes("utf8"));
        byte[] data = signature.sign();
        return Base64.encode(data);
    }

    public static boolean verify(PublicKey publicKey, String text, String sign) throws Exception {
        Signature signature = Signature.getInstance("SHA1WithRSA", provider);
        signature.initVerify(publicKey);
        text = md5(text);
        signature.update(text.getBytes("UTF-8"));
        byte[] signed = Base64.decode(sign);
        return signature.verify(signed);
    }

    //目前使用
    public static boolean verify(String text, String sign, String cacheParams) throws Exception {
        JSONObject resp = JSONObject.parseObject(cacheParams);
        String certPath = resp.getString("42");
        PublicKey publicKey = loadRsaTLPublicKey(certPath);
        Signature signature = Signature.getInstance("SHA1WithRSA", provider);
        signature.initVerify(publicKey);
        text = md5(text);
        signature.update(text.getBytes("UTF-8"));
        byte[] signed = Base64.decode(sign);
        return signature.verify(signed);
    }

    public static String md5(String src) {
        String result = "";

        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            result = Base64.encode(md.digest(src.getBytes("utf-8")));
        } catch (Exception var3) {
            var3.printStackTrace();
        }

        return result;
    }

    public static void main(String[] args) throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException {
        IRedisStringUtils redisStringUtils = new RedisStringUtilsImpl();
        final String key = "allInPay";
        String cacheParams = "aaa";
        Boolean cacheSuccess = redisStringUtils.set(key, cacheParams, 50L, Constants.REDIS_PAY_INDEX);
        String s = redisStringUtils.get(key, Constants.REDIS_PAY_INDEX);
        System.out.println(s);
        // 获取私钥信息
/*        InputStream pdfis = null;
        try {
            URL url = URLUtil.toUrlForHttp("https://shushangyun01.oss-cn-shenzhen.aliyuncs.com/1902271423530473681642a40545aa1422c9a045bb2612ea67b.pfx");
            pdfis = url.openStream();
        } catch (Exception e) {
            log.error("根据url下载文件失败", e);
        }
        String password = "123456";
        char[] storePwd = password.toCharArray();
        char[] keyPwd = password.toCharArray();
        KeyStore ks = KeyStore.getInstance("pkcs12");
        ks.load(pdfis, storePwd);
        PrivateKey var7 = null;
        String alias = "1902271423530473681";
        var7 = (PrivateKey) ks.getKey(alias, keyPwd);
        privateKey = (RSAPrivateKey) var7;*/
    }

 /*   *//**
     * 获取商户私钥
     *
     * @param alias    appId
     * @param path     私钥证书所在位置
     * @param password 私钥证书密码
     * @return 密钥
     */
    public static PrivateKey loadRsaPrivateKey(String alias, String path, String password) {
        // 获取私钥信息
        File file = null;
        InputStream pdfis = null;
        PrivateKey var7 = null;
        //从订单服务查询支付参数
        try {
            URL url = URLUtil.toUrlForHttp(path);
            pdfis = url.openStream();
        } catch (Exception e) {
          //  log.error("根据url下载文件失败", e);
        }
        try {
            char[] storePwd = password.toCharArray();
            char[] keyPwd = password.toCharArray();
            KeyStore ks = KeyStore.getInstance("pkcs12");
            ks.load(pdfis, storePwd);
            var7 = (PrivateKey) ks.getKey(alias, keyPwd);
            privateKey = (RSAPrivateKey) var7;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (pdfis != null) {
                try {
                    pdfis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return var7;
    }

    /**
     * 获取商户私钥
     *
     * @param alias    appId
     * @param path     私钥证书所在位置
     * @param password 私钥证书密码
     * @return 密钥
     */
  /*  public static PrivateKey loadPrivateKey(String alias, String path, String password) {
        // 获取私钥信息
        File file = null;
        InputStream pdfis = null;
        PrivateKey var7 = null;
        password = "123456";
        alias = "1902271423530473681";
       *//* String urlPfx = "https://shushangyun01.oss-cn-shenzhen.aliyuncs.com/1902271423530473681642a40545aa1422c9a045bb2612ea67b.pfx";
        //从订单服务查询支付参数
        try {
            URL url = URLUtil.toUrlForHttp(urlPfx);
            pdfis = url.openStream();
        } catch (Exception e) {
            log.error("根据url下载文件失败", e);
        }*//*
        try {
            file = ResourceUtils.getFile("classpath:allInPay/1902271423530473681.pfx");
            path = file.getPath();
            pdfis = new FileInputStream(path);
            char[] storePwd = password.toCharArray();
            char[] keyPwd = password.toCharArray();
            KeyStore ks = KeyStore.getInstance("pkcs12");
            ks.load(pdfis, storePwd);
            var7 = (PrivateKey) ks.getKey(alias, keyPwd);
            privateKey = (RSAPrivateKey) var7;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (pdfis != null) {
                try {
                    pdfis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return var7;
    }
*/
    /**
     * 获取商户公钥
     *
     * @param alias    appId
     * @param path     私钥证书所在位置
     * @param password 私钥证书密码
     * @return
     * @throws Exception
     */
    public static PublicKey loadPublicKey(String alias, String path, String password) {
        FileInputStream ksfis = null;
        alias = "1902271423530473681";
        // path = "E:\\Work\\1902271423530473681.pfx";
        File file = null;
        password = "123456";
        PublicKey var6 = null;
        try {
            file = ResourceUtils.getFile("classpath:allInPay/1902271423530473681.pfx");
            path = file.getPath();
            KeyStore ks = KeyStore.getInstance("pkcs12");
            ksfis = new FileInputStream(path);
            char[] storePwd = password.toCharArray();
            ks.load(ksfis, storePwd);
            var6 = ks.getCertificate(alias).getPublicKey();
            publicKey = (RSAPublicKey) var6;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (ksfis != null) {
                try {
                    ksfis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        return var6;
    }

    /**
     * 获取商户公钥
     *
     * @param alias    appId
     * @param path     私钥证书所在位置
     * @param password 私钥证书密码
     * @return 操作结果
     * @throws Exception 异常
     */
    public static PublicKey loadRsaPublicKey(String alias, String path, String password) {
        PublicKey var6 = null;
        InputStream pdfis = null;
        try {
            URL url = URLUtil.toUrlForHttp(path);
            pdfis = url.openStream();
        } catch (Exception e) {
          //  log.error("根据URL下载文件失败", e);
        }
        try {
            KeyStore ks = KeyStore.getInstance("pkcs12");
            char[] storePwd = password.toCharArray();
            ks.load(pdfis, storePwd);
            var6 = ks.getCertificate(alias).getPublicKey();
            publicKey = (RSAPublicKey) var6;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (pdfis != null) {
                try {
                    pdfis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        return var6;
    }

    /**
     * 获取通联公钥
     *
     * @param certPath 公钥所在路径
     * @return 返回公钥信息
     * @throws Exception
     */
    public static PublicKey loadTLPublicKey(String certPath) {
        FileInputStream certInputStream = null;
        PublicKey pubKey = null;
        try {
            File file = ResourceUtils.getFile("classpath:allInPay/TLCert-test.cer");
            String path = file.getPath();
            // certPath = "E:\\Work\\TLCert-test.cer";


            CertificateFactory certificatefactory = null;
            certificatefactory = CertificateFactory.getInstance("X.509");

            certInputStream = new FileInputStream(path);
            X509Certificate Cert = (X509Certificate) certificatefactory.generateCertificate(certInputStream);
            pubKey = Cert.getPublicKey();
            tlPublicKey = (RSAPublicKey) pubKey;
        } catch (IOException var8) {
            var8.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } finally {
            if (certInputStream != null) {
                try {
                    certInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        return pubKey;
    }

    /**
     * 获取通联公钥
     *
     * @param certPath 公钥所在路径
     * @return 返回公钥信息
     * @throws Exception
     */
    public static PublicKey loadRsaTLPublicKey(String certPath) {
        InputStream certInputStream = null;
        PublicKey pubKey = null;
        try {
            URL url = URLUtil.toUrlForHttp(certPath);
            certInputStream = url.openStream();
        } catch (Exception e) {
          //  log.error("根据URL下载文件失败", e);
        }
        try {

            CertificateFactory certificatefactory = null;
            certificatefactory = CertificateFactory.getInstance("X.509");
            X509Certificate Cert = (X509Certificate) certificatefactory.generateCertificate(certInputStream);
            pubKey = Cert.getPublicKey();
            tlPublicKey = (RSAPublicKey) pubKey;
        } catch (CertificateException e) {
            e.printStackTrace();
        } finally {
            if (certInputStream != null) {
                try {
                    certInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }

        return pubKey;
    }

    public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) throws Exception {
        KeyFactory keyFac = null;

        try {
            keyFac = KeyFactory.getInstance("RSA", provider);
        } catch (NoSuchAlgorithmException var6) {
            throw var6;
        }

        RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(modulus), new BigInteger(publicExponent));

        try {
            return (RSAPublicKey) keyFac.generatePublic(pubKeySpec);
        } catch (InvalidKeySpecException var5) {
            throw var5;
        }
    }

    public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) throws Exception {
        KeyFactory keyFac = null;

        try {
            keyFac = KeyFactory.getInstance("RSA", provider);
        } catch (NoSuchAlgorithmException var6) {
            throw var6;
        }

        RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus), new BigInteger(privateExponent));

        try {
            return (RSAPrivateKey) keyFac.generatePrivate(priKeySpec);
        } catch (InvalidKeySpecException var5) {
            throw var5;
        }
    }

    public static byte[] encrypt(Key key, byte[] data) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
            cipher.init(1, key);
            byte[] bytes = cipher.doFinal(data);
            return bytes;
        } catch (Exception var4) {
            throw var4;
        }
    }

    public static byte[] decrypt(Key key, byte[] raw) throws Exception {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
            cipher.init(2, key);
            byte[] bytes = cipher.doFinal(raw);
            return bytes;
        } catch (Exception var4) {
            throw var4;
        }
    }

    public static String getPublicKeyString(RSAPublicKey key) throws Exception {
        String exponent = byte2hex(key.getPublicExponent().toByteArray());
        String modulus = byte2hex(key.getModulus().toByteArray());
        StringBuffer sb = new StringBuffer();
        sb.append(modulus).append(" ").append(exponent);
        return sb.toString();
    }

    public static String getPrivateKeyString(RSAPrivateKey key) throws Exception {
        String exponent = byte2hex(key.getPrivateExponent().toByteArray());
        String modulus = byte2hex(key.getModulus().toByteArray());
        StringBuffer sb = new StringBuffer();
        sb.append(modulus).append(" ").append(exponent);
        return sb.toString();
    }

    public static String byte2hex(byte[] bytes) {
        StringBuffer retString = new StringBuffer();

        for (int i = 0; i < bytes.length; ++i) {
            String hex = Integer.toHexString(bytes[i] & 255);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }

            retString.append(hex.toUpperCase());
        }

        return retString.toString();
    }

    public static String byte2hex(byte[] bytes, int index, int len) {
        StringBuffer retString = new StringBuffer();

        for (int i = 0; i < bytes.length; ++i) {
            String hex = Integer.toHexString(bytes[i] & 255);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }

            retString.append(hex.toUpperCase());
        }

        return retString.toString();
    }

    public static byte[] hex2byte(String src) {
        if (src.length() % 2 != 0) {
            src = src + "0";
        }

        byte[] ret = new byte[src.length() / 2];
        byte[] tmp = src.getBytes();

        for (int i = 0; i < src.length() / 2; ++i) {
            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
        }

        return ret;
    }

    public static byte uniteBytes(byte src0, byte src1) {
        byte _b0 = Byte.decode("0x" + new String(new byte[]{src0}));
        _b0 = (byte) (_b0 << 4);
        byte _b1 = Byte.decode("0x" + new String(new byte[]{src1}));
        byte ret = (byte) (_b0 ^ _b1);
        return ret;
    }

    public static String getRandomNum() {
        SecureRandom sr = new SecureRandom();
        return "" + sr.nextInt(10) + sr.nextInt(10) + sr.nextInt(10);
    }

    public static boolean ipCheck(String ip) {
        if (ip != null && !ip.isEmpty()) {
            String regex = "^(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|[1-9])\\.(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|[1-9])$";
            return ip.matches(regex);
        } else {
            return false;
        }
    }

    public static String getIpNum(String ip) {
        StringBuffer sb = new StringBuffer();
        String[] len = ip.split("\\.");

        for (int i = 0; i < len.length; ++i) {
            String s = len[i];
            if (s.length() == 3) {
                sb.append(s);
            } else if (s.length() == 2) {
                sb.append(s).append("0");
            } else if (s.length() == 1) {
                sb.append(s).append("00");
            }
        }

        return sb.toString();
    }

    public static String base64EncodeData(String data) throws Exception {
        return gwPublicKey != null ? Base64.encode(encrypt(gwPublicKey, data.getBytes())) : "";
    }
    public static String base64EncodeData(String data,String cacheParams) throws Exception {
        return gwPublicKey != null ? Base64.encode(encrypt(gwPublicKey, data.getBytes())) : "";
    }
    public static String base64EncodeData(RSAPublicKey pubKey, String data) throws Exception {
        return Base64.encode(encrypt(pubKey, data.getBytes()));
    }

}
